home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / restore.arc / GETOPT.C next >
C/C++ Source or Header  |  1988-01-07  |  3KB  |  117 lines

  1. /*
  2.  *----------------------------------------------------------------------------
  3.  *
  4.  *    This getopt is derived from one posted to the net as part of
  5.  *    the smail 2.5 distribution.  I have had to patch it to allow
  6.  *    for a few MWC 2.0 and/or Atari TOS peculiarities.  These patches
  7.  *    are noted in comments marked `:rwa:'.  The orginal header follows.
  8.  *
  9.  *----------------------------------------------------------------------------
  10.  */
  11.  
  12. /*
  13. **    @(#)getopt.c    2.5 (smail) 9/15/87
  14. */
  15.  
  16. /*
  17.  * Here's something you've all been waiting for:  the AT&T public domain
  18.  * source for getopt(3).  It is the code which was given out at the 1985
  19.  * UNIFORUM conference in Dallas.  I obtained it by electronic mail
  20.  * directly from AT&T.  The people there assure me that it is indeed
  21.  * in the public domain.
  22.  * 
  23.  * There is no manual page.  That is because the one they gave out at
  24.  * UNIFORUM was slightly different from the current System V Release 2
  25.  * manual page.  The difference apparently involved a note about the
  26.  * famous rules 5 and 6, recommending using white space between an option
  27.  * and its first argument, and not grouping options that have arguments.
  28.  * Getopt itself is currently lenient about both of these things White
  29.  * space is allowed, but not mandatory, and the last option in a group can
  30.  * have an argument.  That particular version of the man page evidently
  31.  * has no official existence, and my source at AT&T did not send a copy.
  32.  * The current SVR2 man page reflects the actual behavor of this getopt.
  33.  * However, I am not about to post a copy of anything licensed by AT&T.
  34.  */
  35.  
  36. /*LINTLIBRARY*/
  37. #define NULL    0
  38. #define EOF    (-1)
  39.  
  40. /*    MWC can't hack the original macro (too complex). I have made it
  41.     simpler and defined a function, prterr(), to do the work. :rwa:        */
  42.  
  43. #define ERR(s, c)    if ( opterr ) prterr( argv, s, c )
  44.  
  45. static void
  46. prterr( argv, s, c )
  47.     char * * argv;
  48.     char * s;
  49.     int c; {
  50.     extern int strlen(), write();
  51.     char errbuf[3];
  52.  
  53.     errbuf[0] = c;
  54.     errbuf[1] = '\r';        /* added \r to pander to TOS :rwa: */
  55.     errbuf[2] = '\n';
  56.  
  57.     (void) write(2, argv[0], (unsigned)strlen(argv[0]));
  58.     (void) write(2, s, (unsigned)strlen(s));
  59.     (void) write(2, errbuf, 3);
  60. }
  61.  
  62. #define strchr index            /* SysV-ism, use v7 routine :rwa: */
  63.  
  64. extern int strcmp();
  65. extern char *strchr();
  66.  
  67. int    opterr = 1;
  68. int    optind = 1;
  69. int    optopt;
  70. char    *optarg;
  71.  
  72. int
  73. getopt(argc, argv, opts)
  74. int    argc;
  75. char    **argv, *opts;
  76. {
  77.     static int sp = 1;
  78.     register int c;
  79.     register char *cp;
  80.  
  81.     if(sp == 1)
  82.         if(optind >= argc ||
  83.            argv[optind][0] != '-' || argv[optind][1] == '\0')
  84.             return(EOF);
  85.         else if(strcmp(argv[optind], "--") == NULL) {
  86.             optind++;
  87.             return(EOF);
  88.         }
  89.     optopt = c = argv[optind][sp];
  90.     if(c == ':' || (cp=strchr(opts, c)) == NULL) {
  91.         ERR(": unknown option, -", c);
  92.         if(argv[optind][++sp] == '\0') {
  93.             optind++;
  94.             sp = 1;
  95.         }
  96.         return('?');
  97.     }
  98.     if(*++cp == ':') {
  99.         if(argv[optind][sp+1] != '\0')
  100.             optarg = &argv[optind++][sp+1];
  101.         else if(++optind >= argc) {
  102.             ERR(": argument missing for -", c);
  103.             sp = 1;
  104.             return('?');
  105.         } else
  106.             optarg = argv[optind++];
  107.         sp = 1;
  108.     } else {
  109.         if(argv[optind][++sp] == '\0') {
  110.             sp = 1;
  111.             optind++;
  112.         }
  113.         optarg = NULL;
  114.     }
  115.     return(c);
  116. }
  117.